package com.zzt.authlog.common;

import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 内容摘要：基本队列对象类
 */

public class BaseQueue implements IQueue {
	private final Log log = LogFactory.getLog(BaseQueue.class);

	// 建立异步线程处理机制
	// 使用线程安全的阻塞队列，替换原来的同步令牌和链表队列
	LinkedBlockingQueue queue = null; // 操作日志队列

	Thread thd = null; // 后台处理线程

	boolean runthd = false; // 线程运行标志

	Object thdControlObj = new Object(); // 后台线程启动/休眠控制令牌

	// 注册的监听队列
	ArrayList listenerqueue = new ArrayList();

	// 队列列表的最大长度
	protected int maxsize = Config.maxsize;

	// 是否显示基类队列调试信息
	protected boolean debug = Config.debug;

	/**
	 * 设置队列的大小
	 */
	public void setMaxSize(int size) {
		maxsize = size;
	}

	public int getMaxSize() {
		return maxsize;
	}

	/**
	 * 注册一个监听队列，本队列对象在出队的时候，将传递给所有注册的队列
	 */
	public void registListener(IQueue queue) {
		listenerqueue.add(queue);
	}

	/**
	 * 启动队列处理线程
	 */
	public void startThread() {
		runthd = true;
		synchronized (thdControlObj) {
			thdControlObj.notify();
		}
	}

	/**
	 * 停止队列处理线程
	 * 
	 */
	public void stopThread() {
		runthd = false;
	}

	/**
	 * 向将业务对象加入到处理队列中，在具体业务子类中可以重载
	 */
	public void putObject(Object obj) {
		if (debug)
			log.debug("操作日志队列长度为" + maxsize);

		// 将日志信息加入日志队列
		try {
			if (debug)
				log.debug("*********** 向队列中添加对象");
			queue.offer(obj);
		} catch (Exception e) {
			e.printStackTrace();
			if (debug)
				log.debug("超过队列最大值，不能添加记录");
		}
	}

	/**
	 * 内容摘要：处理出队对象方法，在具体业务子类中可以重载
	 */
	public void popObject(Object obj) {
		// 将队列中的值传递给监听队列
		if (listenerqueue != null && listenerqueue.size() > 0) {
			for (int i = 0; i < listenerqueue.size(); i++) {
				IQueue listener = (IQueue) listenerqueue.get(i);
				listener.putObject(obj);
			}
		}
		if (debug)
			log.debug("处理对象：" + obj.toString());
		if (debug)
			log.debug("dealOneObj方法需要重载");
	}

	/**
	 * 构造函数
	 * 
	 */
	public BaseQueue() {
		init();
	}

	/**
	 * 启动异步处理线程
	 * 
	 */
	private void init() {
		// 建立异步线程处理机制
		queue = new LinkedBlockingQueue(maxsize);
		thd = new Thread(new QueueThread());
		thd.setDaemon(true);
		thd.start();
		log.info("BaseQueue statrt，Queue=" + this.getClass().getName() + "; thread=" + thd.toString());
	}

	/**
	 * 内容摘要： 后台处理线程类
	 * 内容描述： 完成队列出队调度处理
	 */
	class QueueThread implements Runnable {
		Object obj = null;

		/**
		 * 内容摘要：线程运行方法
		 */
		public void run() {
			while (true) {
				// 线程控制操作标志
				try {
					if (!runthd) {
						synchronized (thdControlObj) {
							thdControlObj.wait();
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				// 处理队列中的一个对象
				try {

					if (debug)
						log.debug("发现队列值项，取第一个对象处理，Queue=" + this.getClass().getName());
					obj = queue.take();

					// 处理队列中的对象
					popObject(obj);
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					obj = null;
				}
			}
		}

	}

	public static void main(String[] args) {
		IQueue queue = new BaseQueue();
		queue.putObject("test obj 1");
		queue.startThread();
		queue.putObject("test obj 2");
		queue.stopThread();
		queue.putObject("test obj 3");
		queue.startThread();
		queue.startThread();
		queue.putObject("test obj 4");
		// queue.stopQueue();
		queue.putObject("test obj 5");
		try {
			Thread.sleep(30 * 1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
